#include "flash_table.h"
#include "drivers.h"

#define INTERNAL_FLASH_SIZE                       0x08080000
#define CONFIG_DATA_SIZE                          0x20
#define RESERVE_END_SIZE                          0x20
#define CONFIG_DATA_START                         (INTERNAL_FLASH_SIZE - CONFIG_DATA_SIZE - RESERVE_END_SIZE)

typedef enum {
    CONFIG_ID_IMMO_STATUS = 0,
    CONFIG_ID_SW_RESTART,
    CONFIG_ID_LOGIN_TIME,
    //SIZE
    CONFIG_ID_SIZE
} ConfigIdEnum;

typedef struct {
    uint8_t id;
    uint16_t size;
} ConfigItem;

ConfigItem configTable[CONFIG_ID_SIZE] =
{
    {CONFIG_ID_IMMO_STATUS, 2},
    {CONFIG_ID_SW_RESTART, 2},
    {CONFIG_ID_LOGIN_TIME, 20},
};

void read_config_data(uint8_t *data)
{
    uint8_t i;

#if 0
    logi("%s", __func__);
    for(i = 0; i < CONFIG_DATA_SIZE; i++) {
        printf("%02x ", data[i]);
    }
    printf("\r\n");
#endif
    bsp_ReadCpuFlash(CONFIG_DATA_START, data, CONFIG_DATA_SIZE);
}

void write_config_data(uint8_t *data)
{
    uint8_t i;

#if 0
    logi("%s", __func__);
    for(i = 0; i < CONFIG_DATA_SIZE; i++) {
        printf("%02x ", data[i]);
    }
    printf("\r\n");
#endif
    bsp_WriteCpuFlash(CONFIG_DATA_START, data, CONFIG_DATA_SIZE);
}

uint8_t config_get_data(uint8_t id, uint8_t *config, uint16_t size)
{
    uint16_t offset = 0;
    uint8_t i;
    uint8_t *data = (uint8_t *)malloc(CONFIG_DATA_SIZE);
    if(!data) {
        loge("failed to malloc %d bytes", CONFIG_DATA_SIZE);
        return FALSE;
    }

    memset(data, 0x00, CONFIG_DATA_SIZE);
    read_config_data(data);
    for(i = 0; i < (id); i++) {
        offset += configTable[i].size;
    }
    memcpy(config, data + offset, size);
    free(data);
    return TRUE;
}

uint8_t config_set_data(uint8_t id, uint8_t *config, uint16_t size)
{
    uint16_t offset = 0;
    uint8_t i;
    uint8_t *data = (uint8_t *)malloc(CONFIG_DATA_SIZE);
    if(!data) {
        loge("failed to malloc %d bytes", CONFIG_DATA_SIZE);
        return FALSE;
    }

    memset(data, 0x00, CONFIG_DATA_SIZE);
    read_config_data(data);
    for(i = 0; i < (id); i++) {
        offset += configTable[i].size;
    }
    memcpy(data + offset, config, size);
    write_config_data(data);
    free(data);
    return TRUE;
}

void iFlash_set_immo(uint8_t status)
{
    uint8_t buf[2];

    buf[0] = status;
    config_set_data(CONFIG_ID_IMMO_STATUS, buf, 2);
}

uint8_t iFlash_get_immo(void)
{
    uint8_t buf[2];

    config_get_data(CONFIG_ID_IMMO_STATUS, buf, 2);

    return buf[0];
}

void iFlash_set_restart_flag(uint8_t status)
{
    uint8_t buf[2];

    buf[0] = status;
    config_set_data(CONFIG_ID_SW_RESTART, buf, 2);
}

uint8_t iFlash_get_restart_flag(void)
{
    uint8_t buf[2];

    config_get_data(CONFIG_ID_SW_RESTART, buf, 2);

    return buf[0];
}

void iFlash_set_login_time(char *buf)
{
    config_set_data(CONFIG_ID_LOGIN_TIME, buf, 20);
}

void iFlash_get_login_time(char *buf)
{
    config_get_data(CONFIG_ID_LOGIN_TIME, buf, 20);
}
